#!/usr/bin/python
# -*- coding: latin-1 -*-

import os, sys, uuid, BaseHTTPServer
sys.path.append("utils")
import rpc_utils, DTOs
from com.xhaus.jyson import JysonCodec as json
from desenhadorOntologia import DesenhadorOntologia, pathToStringURI, AddAxiom
from DTOs import FotoInfo, Equipa, Jogador, Ocorrencia

strPhysicalURI = pathToStringURI( os.getcwd(), "/taxionomia/futebol2.owl" )
strOntologyURI = 'http://Futebol2'

class Anotador( DesenhadorOntologia ):
   def __init__( self ):
      DesenhadorOntologia.__init__( self, strPhysicalURI, strOntologyURI )
      self.ler()
      
   def adicionarPropriedadeDeDados( self, propertyOWL, individualOWL, data ):
      # Now create the actual assertion (triple), as an object property assertion axiom:
      # individualOWL --> propertyOWL --> data
      assertion = self.factory.getOWLDataPropertyAssertionAxiom( individualOWL, propertyOWL, data )
      # To do this we create an AddAxiom change object.
      addAxiom = AddAxiom( self.ontology, assertion )
      # We now use the manager to apply the change
      self.manager.applyChange( addAxiom )
      
   def obterPropriedadeDeDados(self, strName, includeFragment=True ):
      # Tecnica identica 'a de "obterClasse"
      return self.obterElemento( strName, self.factory.getOWLDataProperty, includeFragment )
   
   def obterIndividuoAnonimo(self, strName):
      return self.obterElemento( str(uuid.uuid4()), self.factory.getOWLIndividual )
      #return self.obterElemento( strName, self.factory.getOWLAnonymousIndividual )
   
   def anota( self, fotoInfo ):
      
      print 'adiciona jogo...'
      #adiciona jogo
      jogo = self.adicionaJogo(fotoInfo)
      
      print 'adiciona bola...'
      #bola = None
      #if fotoInfo.bolaEsta <> None and fotoInfo.bolaEsta <> '':
      bola = self.adicionaBola(jogo['instanciaJogo'], fotoInfo.bolaEsta, jogo['instanciaFotografia'])
      
      print 'adiciona equipas...'
      #adiciona equipas ao jogo
      instanciasEquipas = self.adicionaEquipas(fotoInfo, jogo['instanciaJogo'], jogo['instanciaFotografia'])
      
      print 'verifica se existem jogadores para adicionar...\n\n'
      # Adiciona os jogadores da equipa
      if len(fotoInfo.equipa1.jogadores) > 0:
         print 'adiciona jogadores da equipa 1'
         self.adicionaJogadores(fotoInfo.equipa1, instanciasEquipas['equipa1'], jogo['instanciaFotografia'])
      
      if len(fotoInfo.equipa2.jogadores) > 0:
         print 'adiciona jogadores da equipa 2'
         self.adicionaJogadores(fotoInfo.equipa2, instanciasEquipas['equipa2'], jogo['instanciaFotografia'])
      
      # grava a ontologia, com os novos individuos adicionados
      print 'A gravar...'
      self.gravar()
      
      return True
   
   def adicionaJogo( self, fotoInfo ):
      classeJogo = self.obterClasse('Jogo')
      classeFoto = self.obterClasse('Fotografia')
      
      print 'FOTO: ', fotoInfo.foto
      
      print 'a criar individuo foto...'
      instanciaFoto = self.obterIndividuo(fotoInfo.foto)
      self.adicionarAxiomaPertenca( instanciaFoto, classeFoto )
      
      print 'a criar individuo anonimo que representa o jogo...'
      #instanciaJogo = self.obterIndividuo(fotoInfo.nomeJogo)
      instanciaJogo = self.obterIndividuoAnonimo(fotoInfo.nomeJogo)
      self.adicionarAxiomaPertenca( instanciaJogo, classeJogo )
      
      temFoto = self.obterPropriedade('temFotografia')
      jogoTemNome = self.obterPropriedadeDados('jogoTemNome')
      self.adicionarPropriedade(temFoto, instanciaJogo, instanciaFoto)
      
      print 'adiciona propriedade, jogoTemNome...'
      print 'nome do jogo = ', fotoInfo.nomeJogo
      self.adicionarPropriedadeDeDados(jogoTemNome, instanciaJogo, fotoInfo.nomeJogo)
            
      print 'devolver instancias de jogo e foto' 
      #return instanciaJogo
      return {
         'instanciaJogo': instanciaJogo,
         'instanciaFotografia': instanciaFoto
      }
      
   def adicionaBola (self, instanciaJogo, local, individuoFotografia):
      classeBola = self.obterClasse('Bola')
      jogoTemBola = self.obterPropriedade('jogoTemBola')
      
      instanciaBola = self.obterIndividuoAnonimo('bola')
      self.adicionarAxiomaPertenca( instanciaBola, classeBola )
      self.adicionarPropriedade(jogoTemBola, instanciaJogo,instanciaBola)
      
      foteDe = self.obterPropriedade('fotoDe')
      self.adicionarPropriedade(foteDe, individuoFotografia, instanciaBola)
      
      if local <> None:
         classeLocal = self.obterClasse(local)
         bolaEsta = self.obterPropriedade('bolaEsta')
         instanciaLocal = self.obterIndividuo('instancia_' + local)
         self.adicionarAxiomaPertenca( instanciaLocal, classeLocal )
         self.adicionarPropriedade(bolaEsta, instanciaBola, instanciaLocal)
         
      return instanciaBola
   
   def adicionaEquipas( self, fotoInfo, instanciaJogo, individuoFotografia ):
      classeEquipa1 = self.obterClasse(fotoInfo.equipa1.tipo)
      classeEquipa2 = self.obterClasse(fotoInfo.equipa2.tipo)
      
      #instanciaJogo = self.obterIndividuo(fotoInfo.nomeJogo)
      
      instanciaEquipa1 = self.obterIndividuoAnonimo(fotoInfo.equipa1.nome)
      instanciaEquipa2 = self.obterIndividuoAnonimo(fotoInfo.equipa2.nome)
      
      jogoTemEquipa = self.obterPropriedade('JogoTemEquipa')
      equipaTemNome = self.obterPropriedadeDeDados('equipaTemNome')
      
      self.adicionarPropriedadeDeDados(equipaTemNome, instanciaEquipa1, fotoInfo.equipa1.nome)
      self.adicionarPropriedadeDeDados(equipaTemNome, instanciaEquipa2, fotoInfo.equipa2.nome)
      self.adicionarPropriedade(jogoTemEquipa, instanciaJogo, instanciaEquipa1)
      self.adicionarPropriedade(jogoTemEquipa, instanciaJogo, instanciaEquipa2)
      self.adicionarAxiomaPertenca( instanciaEquipa1, classeEquipa1 )
      self.adicionarAxiomaPertenca( instanciaEquipa2, classeEquipa2 )
      
      foteDe = self.obterPropriedade('fotoDe')
      self.adicionarPropriedade(foteDe, individuoFotografia, instanciaEquipa1)
      self.adicionarPropriedade(foteDe, individuoFotografia, instanciaEquipa2)

      return {
         'equipa1': instanciaEquipa1,
         'equipa2': instanciaEquipa2
      }
   
   def adicionaJogadores( self, equipa, individuoEquipa, individuoFotografia):
      
      if equipa == None: return
      
      classeJogador = self.obterClasse('Jogador')
      
      #individuoEquipa = self.obterIndividuo(equipa.nome)
      #equipaTemJogador = self.obterPropriedade('EquipaTemJogador')
      
      jogadorTemEquipa = self.obterPropriedade('temEquipa')
      jogadorTemNome = self.obterPropriedadeDeDados('JogadortemNome')
      jogadorECanhoto = self.obterPropriedadeDeDados('eChanhoto')
      
      foteDe = self.obterPropriedade('fotoDe')
      
      for jogador in equipa.jogadores:
         #individuoJogador = self.obterIndividuo(jogador.nome)
         individuoJogador = self.obterIndividuoAnonimo(jogador.nome)
         
         self.adicionarAxiomaPertenca( individuoJogador, classeJogador )
         self.adicionarPropriedade(jogadorTemEquipa, individuoJogador, individuoEquipa)
         #self.adicionarPropriedade(equipaTemJogador, individuoEquipa, individuoJogador)   <-- inferido
         self.adicionarPropriedadeDeDados(jogadorTemNome, individuoJogador, jogador.nome)
         self.adicionarPropriedadeDeDados(jogadorECanhoto, individuoJogador, jogador.eCanhoto)
         
         self.adicionarPropriedade(foteDe, individuoFotografia, individuoJogador)
         
         #adiciona ocorrencias do jogador no jogo
         if len(jogador.ocorrencias) > 0:
            self.adicionaOcorrencia(jogador, individuoJogador, individuoFotografia, jogador.ocorrencias)
      
   def adicionaOcorrencia( self, jogador, individuoJogador, individuoFotografia, ocorrencias ):
      
      print 'A anotar ocorrencias do jogador ', jogador.nome
      #individuoJogador = self.obterIndividuo(jogador.nome)
      
      foteDe = self.obterPropriedade('fotoDe')
      
      for ocorrencia in ocorrencias:
         
         if ocorrencia.fazCorte:
            print 'Adiciona fazCorte'
            classCorte = self.obterClasse(ocorrencia.fazCorte)
            instanciaCorte = self.obterIndividuo('instancia_' + ocorrencia.fazCorte)
            self.adicionarAxiomaPertenca( instanciaCorte, classCorte )
            
            fazCorte = self.obterPropriedade('fazCorte')
            self.adicionarPropriedade(fazCorte, individuoJogador, instanciaCorte)
            self.adicionarPropriedade(foteDe, individuoFotografia, instanciaCorte)
            
            
         if ocorrencia.fazFalta:
            print 'Adiciona fazFalta'
            classFalta = self.obterClasse(ocorrencia.fazFalta)
            instanciaFalta = self.obterIndividuo('instancia_' + ocorrencia.fazFalta)
            self.adicionarAxiomaPertenca( instanciaFalta, classFalta )
            
            fazFalta = self.obterPropriedade('fazFalta')
            self.adicionarPropriedade(fazFalta, individuoJogador, instanciaFalta)
            self.adicionarPropriedade(foteDe, individuoFotografia, instanciaFalta)
            
         if ocorrencia.bolaParada:
            print 'Adiciona bolaParada'
            classBolaParada = self.obterClasse(ocorrencia.bolaParada)
            instanciaBolaParada = self.obterIndividuo('instancia_' + ocorrencia.bolaParada)
            self.adicionarAxiomaPertenca( instanciaBolaParada, classBolaParada )
            
            bateBolaParada = self.obterPropriedade('bateBolaParada')
            self.adicionarPropriedade(bateBolaParada, individuoJogador, instanciaBolaParada)         
            self.adicionarPropriedade(foteDe, individuoFotografia, instanciaBolaParada)
            
            # se bola parada = Penalti
            if ocorrencia.bolaParada == 'Penalti':
               classFalta = self.obterClasse( 'Falta' )
               classArea = self.obterClasse( 'Area' )
               
               fazFalta = self.obterPropriedade('fazFalta')
               ocorrenciaEm = self.obterPropriedade('ocorrenciaEm')
               
               instanciaFalta = self.obterIndividuo('instancia_Falta')
               instanciaArea = self.obterIndividuo('instancia_Area')
               self.adicionarAxiomaPertenca( instanciaFalta, classFalta )
               self.adicionarAxiomaPertenca( instanciaArea, classArea )
               self.adicionarPropriedade(fazFalta, instanciaBolaParada, instanciaFalta)
               self.adicionarPropriedade(ocorrenciaEm, instanciaBolaParada, instanciaArea)
            
            # se bola parada = Livre
            if ocorrencia.bolaParada == 'Livre':
               classFalta = self.obterClasse( 'Falta' )
               instanciaFalta = self.obterIndividuo('instancia_Falta')
               
               fazFalta = self.obterPropriedade('fazFalta')
               
               self.adicionarAxiomaPertenca( instanciaFalta, classFalta )
               self.adicionarPropriedade(fazFalta, instanciaBolaParada, instanciaFalta)
         
         if ocorrencia.remate:
            print 'Adiciona remate'
            classRemate = self.obterClasse( ocorrencia.remate )
            instanciaRemate = self.obterIndividuo( 'instancia_' + ocorrencia.remate )
            self.adicionarAxiomaPertenca( instanciaRemate, classRemate )
            
            fazRemate = self.obterPropriedade('fazRemate')
            self.adicionarPropriedade(fazRemate, individuoJogador, instanciaRemate)          
            self.adicionarPropriedade(foteDe, individuoFotografia, instanciaRemate)
            
         if ocorrencia.golo:
            print 'Adiciona golo'
            classeGolo = self.obterClasse( 'Golo' )
            classeBaliza = self.obterClasse( 'Baliza' )
            instanciaGolo = self.obterIndividuo( 'golo' )
            instanciaBaliza = self.obterIndividuo( 'instancia_Baliza' )
            self.adicionarAxiomaPertenca( instanciaGolo, classeGolo )
            self.adicionarAxiomaPertenca( instanciaBaliza, classeBaliza )
            
            marcaGolo = self.obterPropriedade( 'marcaGolo' )
            bolaEsta = self.obterPropriedade( 'bolaEsta' )
            self.adicionarPropriedade( marcaGolo, individuoJogador, instanciaGolo )
            self.adicionarPropriedade(bolaEsta, instanciaGolo, instanciaBaliza)
            self.adicionarPropriedade(foteDe, individuoFotografia, instanciaGolo)
         
         if ocorrencia.local:
            print 'Adiciona local'
            classeZonaDoCampo = self.obterClasse( ocorrencia.local )
            instanciaLocal = self.obterIndividuo('instancia_' + ocorrencia.local )
            self.adicionarAxiomaPertenca( instanciaLocal, classeZonaDoCampo )
            
            ocorrenciaEm = self.obterPropriedade( 'ocorrenciaEm' )
            self.adicionarPropriedade( ocorrenciaEm, individuoJogador, instanciaLocal )
            self.adicionarPropriedade(foteDe, individuoFotografia, instanciaLocal)
         
         if ocorrencia.festeja:
            print 'Adiciona festejo'
            classeFesteja = self.obterClasse( 'Festejo' )
            instanciaFestejo = self.obterIndividuo( 'festejo' )
            self.adicionarAxiomaPertenca( instanciaFestejo, classeFesteja )
            
            jogadorFesteja = self.obterPropriedade( 'jogadorFesteja' )
            self.adicionarPropriedade( jogadorFesteja, individuoJogador, instanciaFestejo )
            self.adicionarPropriedade(foteDe, individuoFotografia, instanciaFestejo)

anotador = Anotador()
class InternalAnotadorHandler(BaseHTTPServer.BaseHTTPRequestHandler):
   def do_GET(self):
      self.headers['Content-Type'] = 'text/html'
      self.wfile.write(rpc_utils.load_template())
   
   def do_POST(self):
      # parse the form data posted
      data = self.rfile.read(int(self.headers['Content-Length']))
      print data
      # begin the response
      self.send_response(200)
      self.end_headers()

      self.headers['Content-Type'] = 'text/plain'

      # process response values and return (ugly hack, access position 2 to retrieve body data)
      self.wfile.write(self.process(data))

   def process(self, data):
      print data
      
      # decode json argument into the foto info dto
      dto_arg = DTOs.obj_dic(json.loads(data))
      
      # query the inference engine with the arg
      rv = anotador.anota(dto_arg)
      
      # encode the return value into json
      print rv
      enc_rv = json.dumps(rv)
      
      return enc_rv

class AnotadorHandler():
   def run(self):
      server = BaseHTTPServer.HTTPServer(('', 8002), InternalAnotadorHandler)
      server.serve_forever()   

      
      
      

if __name__ == "__main__":
   ##############################################
   ###### Jogo 1
   ##############################################
   
   print 'A criar o jogo 1 para anotar...'
   jogo = FotoInfo()
   jogo.equipa1 = Equipa()
   jogo.equipa2 = Equipa()
   jogo.bolaEsta = 'Defesa'
   jogo.nomeJogo = 'Final2010'
   jogo.foto = '1.jpg'
   
   jogo.equipa1.nome = "Os_Primeiros"
   jogo.equipa1.tipo = 'EquipaAtacante'  
   jogo.equipa1.jogadores = [ Jogador() ]
   jogo.equipa1.jogadores[0].nome = "ZeManel"
   jogo.equipa1.jogadores[0].equipa = jogo.equipa1
   jogo.equipa1.jogadores[0].eCanhoto = True
   jogo.equipa1.jogadores[0].ocorrencias = [ Ocorrencia() ]
   jogo.equipa1.jogadores[0].ocorrencias[0].fazCorte = 'Carrinho'
   jogo.equipa1.jogadores[0].ocorrencias[0].fazFalta = 'Agressao'
   jogo.equipa1.jogadores[0].ocorrencias[0].bolaParada = 'Penalti'
   jogo.equipa1.jogadores[0].ocorrencias[0].remate = 'RemateCabeca'
   jogo.equipa1.jogadores[0].ocorrencias[0].golo = True
   jogo.equipa1.jogadores[0].ocorrencias[0].local = 'Baliza'
   jogo.equipa1.jogadores[0].ocorrencias[0].festeja = True
   
   jogo.equipa2.nome = "Os_Segundos"
   jogo.equipa2.tipo = 'EquipaDefensora'
   jogo.equipa2.jogadores = [ Jogador() ]
   jogo.equipa2.jogadores[0].nome = "ZeManel"
   jogo.equipa2.jogadores[0].equipa = jogo.equipa1
   jogo.equipa2.jogadores[0].eCanhoto = True
   jogo.equipa2.jogadores[0].ocorrencias = [ Ocorrencia() ]
   jogo.equipa2.jogadores[0].ocorrencias[0].fazCorte = 'Carrinho'
   jogo.equipa2.jogadores[0].ocorrencias[0].fazFalta = 'Agressao'
   jogo.equipa2.jogadores[0].ocorrencias[0].bolaParada = 'Canto'
   jogo.equipa2.jogadores[0].ocorrencias[0].remate = 'RemateCabeca'
   jogo.equipa2.jogadores[0].ocorrencias[0].golo = True
   jogo.equipa2.jogadores[0].ocorrencias[0].local = 'Baliza'
   jogo.equipa2.jogadores[0].ocorrencias[0].festeja = True
   
   
   print 'A criar anotador...'
   a = Anotador()
   
   print '\n\n\n\n\nVou anotar!\n\n\n\n\n'
   a.anota(jogo)
   print 'jogo 1 anotado'
   
   ##############################################
   ###### Jogo 2
   ##############################################
   
   print '\n\nprint a criar jogo2'
   jogo = FotoInfo()
   jogo.equipa1 = Equipa()
   jogo.equipa2 = Equipa()
   jogo.bolaEsta = 'Defesa'
   jogo.nomeJogo = 'Final2011'
   jogo.foto = '2.jpg'
   
   jogo.equipa1.nome = "Os_Primeiros"
   jogo.equipa1.tipo = 'EquipaDefensora'
   jogo.equipa1.jogadores = [ Jogador() ]
   jogo.equipa1.jogadores[0].nome = "ZeManel"
   jogo.equipa1.jogadores[0].equipa = jogo.equipa1
   jogo.equipa1.jogadores[0].eCanhoto = True
   jogo.equipa1.jogadores[0].ocorrencias = [ Ocorrencia() ]
   jogo.equipa1.jogadores[0].ocorrencias[0].fazCorte = 'Carrinho'
   jogo.equipa1.jogadores[0].ocorrencias[0].bolaParada = 'Livre'
   
   jogo.equipa2.nome = "Os_Segundos"
   jogo.equipa2.tipo = 'EquipaAtacante'
   jogo.equipa2.jogadores = [ Jogador() ]
   jogo.equipa2.jogadores[0].nome = "ZeMiguel"
   jogo.equipa2.jogadores[0].equipa = jogo.equipa2
   jogo.equipa2.jogadores[0].eCanhoto = False
   jogo.equipa2.jogadores[0].ocorrencias = [ Ocorrencia() ]
   jogo.equipa2.jogadores[0].ocorrencias[0].fazCorte = 'Carrinho'

   print '\n\n\n\n\nVou anotar!\n\n\n\n\n'
   a.anota(jogo)
   print 'jogo 2 anotado'
   
   #################
   ## teste
   #################
   
   #classeEquipa1 = a.obterClasse('EquipaAtacante')
   #e1 = a.obterIndividuoAnonimo('Equipa1')
   #a.adicionarAxiomaPertenca( e1, classeEquipa1 )
   
   #instanciaEquipa1 = a.obterIndividuoAnonimo('Equipa2')
   #a.adicionarAxiomaPertenca( instanciaEquipa1, classeEquipa1 )
   
   #e2 = a.obterIndividuoAnonimo('Equipa1')
   #a.adicionarAxiomaPertenca( e2, classeEquipa1 )
   #a.gravar()
   
